// =============================================================
// CChord
// ---------------------------------------
// Author : Woo-Hyun Kim
// Email : woorung@icu.ac.kr or woorung@nhncorp.com
// Date : Oct. 9, 2007
// =============================================================
#include "CChord.h"

CChord::CChord() : CDHT()
{
	init();
}

CChord::CChord(char *host, int port) : CDHT(host, port)
{
	init();
}

CChord::~CChord()
{
	fin();
}

void CChord::init()
{
}

void CChord::fin()
{
}

// lookup in local spaces
int CChord::local_spaces(char *ip)
{
	if(local_skeys.size()<1) {
		map<string,CServiceInfo> lspaces;
		lspaces = _llookup(ip, lspaces);

		map<string,CServiceInfo>::iterator local = lspaces.begin();
		for(int hit=0;local!=lspaces.end();) {
			local_skeys[hit++] = local->first;

			local++;
		}
	}

	return local_skeys.size();
}

vector<CServiceInfo> &CChord::llookup(char *ip, vector<CServiceInfo> &ls)
{
	int n = local_spaces(ip);

	for(int i=0;i<local_skeys.size();i++) ls.push_back(workspaces[local_skeys[i]]);

	return ls;
}

vector<CServiceInfo> &CChord::lookup(vector<CServiceInfo> &all)
{
	map<string,CServiceInfo>::iterator found = workspaces.begin();
	while(found!=workspaces.end()) {
		all.push_back(found->second);

		found++;
	}

	return all;
}

CServiceInfo &CChord::lookup(char *key)
{
	map<string,CServiceInfo>::iterator found;
	found = _lookup(key, found);

	return found->second;
}

CServiceInfo &CChord::predecessor(char *key)
{
	map<string,CServiceInfo>::iterator found;
	found = _lookup(key, found);

	if(found==workspaces.begin()) found = workspaces.end();

	found--;

#ifdef DEBUG
	cout << "======================================" << endl;
	cout << "/////////////// lookup ///////////////" << endl;
	cout << "key = " << key << ", space_name = " << this->get_rtype() << endl;
	cout << "found space = " << found->second.getName() << endl;
	cout << "found space = " << found->second.getIP() << endl;
	cout << "found space = " << found->second.getPort() << endl;
	cout << "found space = " << found->second.getCPU() << endl;
	cout << "found space = " << found->second.getLoad() << endl;
	cout << "======================================" << endl;
#endif

	return found->second;
}

CServiceInfo &CChord::successor(char *key)
{
	map<string,CServiceInfo>::iterator found;
	found = _lookup(key, found);

	found++;

	if(found==workspaces.end()) found = workspaces.begin();

#ifdef DEBUG
	cout << "======================================" << endl;
	cout << "/////////////// lookup ///////////////" << endl;
	cout << "key = " << key << ", space_name = " << this->get_rtype() << endl;
	cout << "found space = " << found->second.getName() << endl;
	cout << "found space = " << found->second.getIP() << endl;
	cout << "found space = " << found->second.getPort() << endl;
	cout << "found space = " << found->second.getCPU() << endl;
	cout << "found space = " << found->second.getLoad() << endl;
	cout << "======================================" << endl;
#endif

	return found->second;
}
